package com.sali.handler;

import com.sali.config.MockConfig;
import com.sali.constants.CommonConstants;
import com.sali.utils.ByteUtil;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @description:
 * @author: sali
 * @date: 2025/2/21 下午10:48.
 * @version: 1.0
 */
@Component
@Slf4j
public class SocketHandler {

    @Getter
    private boolean connectionFlag = false;

    @Resource
    private MockConfig mockConfig;


    private Socket clientSocket;

    private AtomicInteger fileCount = new AtomicInteger();


    /**
    * description: 开启 tcp socket连接
    **/
    public void start() {
        boolean isConnection = false;
        for (int i = 0; i < CommonConstants.DEFAULT_COUNT; i++) {
            isConnection = this.connection();
            if (isConnection) {
                break;
            }
            try {
                log.info("连接服务端失败！！5s后重试....");
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        if (isConnection) {
            connectionFlag = isConnection;
            log.info("客户端启动成功");
        } else {
            log.error("客户端连接失败！！1");
            System.exit(1);
        }
    }

    /**
    * description: socket 连接
    **/
    public boolean connection() {
        SocketAddress socketAddress = new InetSocketAddress(mockConfig.getServerIp(), mockConfig.getServerPort());
        clientSocket = new Socket();
        boolean result = false;
        try {
            clientSocket.connect(socketAddress);
            result = true;
        } catch (IOException e) {
            log.error(CommonConstants.ERR_MSG, e.getMessage());
        }
        return result;
    }

    /**
     * 把待处理数据发送到总线
     */
    public void handle(List<String> datas) {
        if (datas == null || datas.isEmpty()) {
            log.warn("待处理数据不合法,请检查数据处理环节是否有bug");
            return;
        }
        log.info("以接受到{}份数据,准备发送到总线处理.....", datas.size());
        datas.forEach(this::sendData);
        log.info("本批次处理完成，共接受到服务器消息{}个", fileCount);
    }

    public void sendData(String message) {
        try {
            DataOutputStream dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
            byte[] bytes = message.getBytes(StandardCharsets.UTF_8);
            dataOutputStream.write(ByteUtil.intToBytes(bytes.length));
            dataOutputStream.flush();
            dataOutputStream.write(bytes);
            dataOutputStream.flush();
            MessageStatistics.getSendMsgCount().getAndIncrement();
            fileCount.getAndAdd(1);
        } catch (IOException e) {
            log.error(CommonConstants.ERR_MSG, e.getMessage());
        }
    }

    @PreDestroy
    public void destory() throws IOException {
        if (clientSocket != null) {
            clientSocket.close();
        }
    }


}
